package com.study.springcache.service.impl;

import com.study.springcache.service.CacheTestService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * @Description: 缓存测试服务类：1、redis、caffeine缓存测试，2、参数版本场景使用
 * @Author: 刘超
 * @Date: 2023-06-13 9:01
 */
@Component
public class CacheTestServiceImpl implements CacheTestService {

    /**
     * 模拟数据库存储版本信息
     */
    private static final Map<String, String> versionMap = new HashMap<>();

    /**
     * 模拟数据库存储数据信息
     */
    private static final Map<String, String> dataMap = new HashMap<>();

    /**
     * 默认版本号
     */
    private static final String DEFAULT_VERSION = "1";

    private static final Logger logger = LoggerFactory.getLogger(CacheTestServiceImpl.class);

    /**
     * redis缓存测试服务
     *
     * @param key
     * @return
     */
    @Override
    @Cacheable(cacheManager = "redisCacheManager", value = "cache1", key = "#key", condition = "#key<3", unless = "#result==null")
    public String getRedisCacheData(int key) {
        logger.info("redisCacheManager 造数据 ... {}", key);
        if (0 == key) {
            return null;
        }
        return "redisCacheManager：" + key;
    }

    /**
     * caffeine缓存测试服务
     *
     * @param key
     * @return
     */
    @Override
    @Cacheable(cacheManager = "caffeineCacheManager", value = "test1", key = "#key", condition = "#key<3", unless = "#result==null")
    public String getCaffeineCacheData(int key) {
        logger.info("caffeineCacheManager 造数据 ... {}", key);
        if (0 == key) {
            return null;
        }
        return "caffeineCacheManager：" + key;
    }

    /**
     * 设置key版本号，version为空时设置为默认版本号
     *
     * @param key
     * @param version
     * @return
     */
    @Override
    @Caching(evict = @CacheEvict(cacheManager = "redisCacheManager", value = "version", key = "#key", beforeInvocation = true),
            put = @CachePut(cacheManager = "redisCacheManager", value = "version", key = "#key"))
    public String setVersion(String key, @Nullable String version) {
        logger.info("set version at " + LocalDateTime.now());
        if (!StringUtils.hasLength(version)) {
            version = DEFAULT_VERSION;
        }
        versionMap.put(key, version);
        return version;
    }

    /**
     * 获取key版本号，当没有设置版本号时设置为默认版本号并返回
     *
     * @param key
     * @return
     */
    @Override
    @Cacheable(cacheManager = "redisCacheManager", value = "version", key = "#key", unless = "#result==null")
    public String getVersion(String key) {
        logger.info("get version at " + LocalDateTime.now());
        String version = versionMap.get(key);
        if (!StringUtils.hasLength(version)) {
            version = DEFAULT_VERSION;
            versionMap.put(key, version);
        }
        return version;
    }

    /**
     * 设置关键字的数据，如果版本号为空，则设置version为默认值
     *
     * @param key
     * @param version
     * @param data
     * @return
     */
    @Override
    @CachePut(cacheManager = "redisCacheManager", value = "data", keyGenerator = "cacheDemoKeyGenerator")
    public String setData(String key, String version, String data) {
        logger.info("set data at " + LocalDateTime.now());
        if (!StringUtils.hasLength(version)) {
            version = DEFAULT_VERSION;
        }
        dataMap.put(key.concat(":").concat(version), data);
        return data;
    }

    /**
     * 获取关键字数据，如果版本号为空，则设置version为默认值
     *
     * @param key
     * @param version
     * @return
     */
    @Override
    @Cacheable(cacheManager = "redisCacheManager", value = "data", keyGenerator = "cacheDemoKeyGenerator", unless = "#result==null")
    public String getData(String key, String version) {
        logger.info("set data at " + LocalDateTime.now());
        if (!StringUtils.hasLength(version)) {
            version = DEFAULT_VERSION;
        }
        return dataMap.get(key.concat(":").concat(version));
    }
}
